


(function (factory) {
 
    if (typeof define === 'function' && define.amd && define.amd.jQuery) {
        //. Register as anonymous module.

        define(['jquery'], factory);
    } else {
        // Browser globals.

        factory(jQuery);
    }
}(function ($) {
	"use strict";

	//Constants
	var LEFT = "left",
		RIGHT = "right",
		UP = "up",
		DOWN = "down",
		IN = "in",
		OUT = "out",

		NONE = "none",
		AUTO = "auto",
		
		SWIPE = "swipe",
		PINCH = "pinch",
		TAP = "tap",
		DOUBLE_TAP = "doubletap",
		LONG_TAP = "longtap",
		HOLD = "hold",
		
		HORIZONTAL = "horizontal",
		VERTICAL = "vertical",

		ALL_FINGERS = "all",
		
		DOUBLE_TAP_THRESHOLD = 10,

		PHASE_START = "start",
		PHASE_MOVE = "move",
		PHASE_END = "end",
		PHASE_CANCEL = "cancel",

		SUPPORTS_TOUCH = 'ontouchstart' in window,
		
		SUPPORTS_POINTER_IE10 = window.navigator.msPointerEnabled && !window.navigator.pointerEnabled,
		
		SUPPORTS_POINTER = window.navigator.pointerEnabled || window.navigator.msPointerEnabled,

		PLUGIN_NS = 'TouchSwipe';

 
	var defaults = {
		fingers: 1, 		
		threshold: 75, 	
		cancelThreshold:null,	
		pinchThreshold:20,
		maxTimeThreshold: null, 
		fingerReleaseThreshold:250, 
		longTapThreshold:500,
		doubleTapThreshold:200,
		swipe: null, 		
		swipeLeft: null, 	
		swipeRight: null, 	
		swipeUp: null, 		
		swipeDown: null, 	
		swipeStatus: null, 	
		pinchIn:null,		
		pinchOut:null,		
		pinchStatus:null,	
		click:null,  
		tap:null,
		doubleTap:null,
		longTap:null, 		
		hold:null, 
		triggerOnTouchEnd: true, 
		triggerOnTouchLeave:false, 
		allowPageScroll: "auto", 
		fallbackToMouseEvents: true,	
		excludedElements:"label, button, input, select, textarea, a, .noSwipe"
	};


 
	$.fn.swipe = function (method) {
	
		var $this = $(this),
			plugin = $this.data(PLUGIN_NS);
 
		
		 
		if (plugin && typeof method === 'string') {
			if (plugin[method]) {
				return plugin[method].apply(this, Array.prototype.slice.call(arguments, 1));
			} else {
				$.error('Method ' + method + ' does not exist on jQuery.swipe');
			}
		}
		 
		else if (!plugin && (typeof method === 'object' || !method)) {

		 	 return init.apply(this, arguments);
		}
 	
		return $this;
	};

	$.fn.swipe.defaults = defaults;
 
	$.fn.swipe.phases = {
		PHASE_START: PHASE_START,
		PHASE_MOVE: PHASE_MOVE,
		PHASE_END: PHASE_END,
		PHASE_CANCEL: PHASE_CANCEL
	};
 
	$.fn.swipe.directions = {
		LEFT: LEFT,
		RIGHT: RIGHT,
		UP: UP,
		DOWN: DOWN,
		IN : IN,
		OUT: OUT
	};
	
 
	$.fn.swipe.pageScroll = {
		NONE: NONE,
		HORIZONTAL: HORIZONTAL,
		VERTICAL: VERTICAL,
		AUTO: AUTO
	};

	 
	$.fn.swipe.fingers = {
		ONE: 1,
		TWO: 2,
		THREE: 3,
		ALL: ALL_FINGERS
	};

 
	function init(options) {
 


		if (!options) {
			options = {};
		}
		
		
        
		options = $.extend({}, $.fn.swipe.defaults, options);

		 
		return this.each(function () {
			var $this = $(this);

		 
			var plugin = $this.data(PLUGIN_NS);

			if (!plugin) {
				plugin = new TouchSwipe(this, options);
				$this.data(PLUGIN_NS, plugin);
			}
		});
	}

	function TouchSwipe(element, options) {
		

        var useTouchEvents = (SUPPORTS_TOUCH || SUPPORTS_POINTER || !options.fallbackToMouseEvents),
            START_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerDown' : 'pointerdown') : 'touchstart') : 'mousedown',
            MOVE_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerMove' : 'pointermove') : 'touchmove') : 'mousemove',
            END_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerUp' : 'pointerup') : 'touchend') : 'mouseup',
            LEAVE_EV = useTouchEvents ? null : 'mouseleave', 
            CANCEL_EV = (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerCancel' : 'pointercancel') : 'touchcancel');

        

	 
		var distance = 0,
			direction = null,
			duration = 0,
			startTouchesDistance = 0,
			endTouchesDistance = 0,
			pinchZoom = 1,
			pinchDistance = 0,
			pinchDirection = 0,
			maximumsMap=null;

		
		
	 
		var $element = $(element);
		 
	 
		var phase = "start";

		 
		var fingerCount = 0; 			

	 
		var fingerData=null;

		 
		var startTime = 0,
			endTime = 0,
			previousTouchEndTime=0,
			previousTouchFingerCount=0,
			doubleTapStartTime=0;

		//Timeouts
		var singleTapTimeout=null,
			holdTimeout=null;
        

	 
		try {

			$element.bind(START_EV, touchStart);
			$element.bind(CANCEL_EV, touchCancel);
		}
		catch (e) {
			$.error('events not supported ' + START_EV + ',' + CANCEL_EV + ' on jQuery.swipe');
		}
 
		 
		this.enable = function () {
			$element.bind(START_EV, touchStart);
			$element.bind(CANCEL_EV, touchCancel);
			return $element;
		};
 	

 		function removeListeners() {
 			$element.unbind(START_EV, touchStart);
 			$element.unbind(CANCEL_EV, touchCancel);
 			$element.unbind(MOVE_EV, touchMove);
 			$element.unbind(END_EV, touchEnd);
 			
		 			
 			if(LEAVE_EV) { 
 				$element.unbind(LEAVE_EV, touchLeave);
 			}
 			
 			setTouchInProgress(false);
 		}

		this.disable = function () {
			removeListeners();
			return $element;
		};

		 
		this.destroy = function () {
			removeListeners();
			$element.data(PLUGIN_NS, null);
			return $element;
		};


        
        this.option = function (property, value) {
            if(options[property]!==undefined) {
                if(value===undefined) {
                    return options[property];
                } else {
                    options[property] = value;
                }
            } else {
                $.error('Option ' + property + ' does not exist on jQuery.swipe.options');
            }

            return null;
        }

    	function touchStart(jqEvent)
    	{	

    		var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent;
    		var ret,evt = SUPPORTS_TOUCH ? event.touches[0] : event;
    		
    		phase = PHASE_START;
    		if (SUPPORTS_TOUCH) {
    			//总数
    			 fingerCount = event.touches.length;
			}else {
				jqEvent.preventDefault(); 
			}
			 
			distance = 0;
			direction = null;
			pinchDirection=null;
			duration = 0;
			startTouchesDistance=0;
			endTouchesDistance=0;
			pinchZoom = 1;
			pinchDistance = 0;
			fingerData=createAllFingerData();
			maximumsMap=createMaximumsData();
			cancelMultiFingerRelease();
		
			 
			if (!SUPPORTS_TOUCH || (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || hasPinches()) {
	 
				createFingerData( 0, evt );
				startTime = getTimeStamp();
				
				if(fingerCount==2) {

					createFingerData( 1, event.touches[1] );
					startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
				}
				

				if (options.swipeStatus || options.pinchStatus) {
					ret = triggerHandler(event, phase);
				}
			}else {
				
				ret = false; 
			}

			if (ret === false) {
				phase = PHASE_CANCEL;
				triggerHandler(event, phase);
				return ret;
			}
			else {

				if (options.hold) {
					holdTimeout = setTimeout($.proxy(function() {
						 
						$element.trigger('hold', [event.target]);
						 
						if(options.hold) {
							ret = options.hold.call($element, event, event.target);
						}
					}, this), options.longTapThreshold );
				}

				setTouchInProgress(true);
			}

            return null;


    	}
    	function touchCancel(jqEvent) {
    		fingerCount = 0;
    		endTime = 0;
    		startTime = 0;
    		startTouchesDistance=0;
    		endTouchesDistance=0;
    		pinchZoom=1;
    		
    	 
    		cancelMultiFingerRelease();
    		
    		setTouchInProgress(false);
    	}

    	function touchLeave(jqEvent) {
    		var event = jqEvent.originalEvent;
    		
    		 
    		if(options.triggerOnTouchLeave) {
    			phase = getNextPhase( PHASE_END );
    			triggerHandler(event, phase);
    		}
    	}

    	function createAllFingerData() {
    		var fingerData=[];
    		for (var i=0; i<=5; i++) {
    			fingerData.push({
    				start:{ x: 0, y: 0 },
    				end:{ x: 0, y: 0 },
    				identifier:0
    			});
    		}
    		
    		return fingerData;
    	} 

    	function createMaximumsData() {
    		var maxData={};
    		maxData[LEFT]=createMaximumVO(LEFT);
    		maxData[RIGHT]=createMaximumVO(RIGHT);
    		maxData[UP]=createMaximumVO(UP);
    		maxData[DOWN]=createMaximumVO(DOWN);
    		
    		return maxData;
    	}

    	function createMaximumVO(dir) {
    	    return { 
    	        direction:dir, 
    	        distance:0
    	    }
    	}

    	function cancelMultiFingerRelease() {
    		previousTouchEndTime = 0;
    		previousTouchFingerCount = 0;
    	}

		function hasPinches() {
		
		 	return !!(options.pinchStatus || options.pinchIn || options.pinchOut);
		}

		function triggerHandler(event, phase) {
			
			var ret = undefined;
			
		
			if(didSwipe() || hasSwipes()) { 
				   
				ret = triggerHandlerForGesture(event, phase, SWIPE);
			} 
				
			 
			else if((didPinch() || hasPinches()) && ret!==false) {
			 
				ret = triggerHandlerForGesture(event, phase, PINCH);
			}
			
			 
			if(didDoubleTap() && ret!==false) {
				//Trigger the tap events...
				ret = triggerHandlerForGesture(event, phase, DOUBLE_TAP);
			}
			
		 
			else if(didLongTap() && ret!==false) {
				 
				ret = triggerHandlerForGesture(event, phase, LONG_TAP);
			}

			 
			else if(didTap() && ret!==false) {
			 
				ret = triggerHandlerForGesture(event, phase, TAP);
			}
			
		 	if(phase === PHASE_END) {
			 
				if (SUPPORTS_TOUCH) {
					if(event.touches.length==0) {
						touchCancel(event);	
					}
				} 
				else {
					touchCancel(event);
				}
			}
				
			return ret;
		}
		
		function didSwipe() {
		 	
			return !!(validateSwipe() && hasSwipes());
		}

		function hasSwipes() {
		 
			return !!(options.swipe || options.swipeStatus || options.swipeLeft || options.swipeRight || options.swipeUp || options.swipeDown);
		}
		

		function validateSwipe() {
			 
			var hasValidTime = validateSwipeTime();
			var hasValidDistance = validateSwipeDistance();	
			var hasCorrectFingerCount = validateFingers();
		    var hasEndPoint = validateEndPoint();
		    var didCancel = didSwipeBackToCancel();	
		   
			var valid =  !didCancel && hasEndPoint && hasCorrectFingerCount && hasValidDistance && hasValidTime;
			
			return valid;
		}

		function didSwipeBackToCancel() {
            var cancelled = false;
    		if(options.cancelThreshold !== null && direction !==null)  {
    		    cancelled =  (getMaxDistance( direction ) - distance) >= options.cancelThreshold;
			}
			
			return cancelled;
		}

		function validateDoubleTap() {
		    if(doubleTapStartTime==null){
		        return false;
		    }
		    var now = getTimeStamp();
		    return (hasDoubleTap() && ((now-doubleTapStartTime) <= options.doubleTapThreshold));
		}

		function didDoubleTap() {
		    
			return !!(validateDoubleTap() && hasDoubleTap());
		}

		function hasDoubleTap() {
			 
			return !!(options.doubleTap) ;
		}

		function didLongTap() {
		 
			return !!(validateLongTap() && hasLongTap());
		}

		function hasLongTap() {
		 
			return !!(options.longTap) ;
		}
		
		function didTap() {
		   
			return !!(validateTap() && hasTap());
		}
		
		function validateTap() {
		    return ((fingerCount === 1 || !SUPPORTS_TOUCH) && (isNaN(distance) || distance < options.threshold));
		}

		function validateLongTap() {
		    
            return ((duration > options.longTapThreshold) && (distance < DOUBLE_TAP_THRESHOLD)); 
		}

		function validateSwipeTime() {
			var result;
			 
			if (options.maxTimeThreshold) {
				if (duration >= options.maxTimeThreshold) {
					result = false;
				} else {
					result = true;
				}
			}
			else {
				result = true;
			}

			return result;
		}

		function validateSwipeDistance() {
			var valid = true;
			 
			if (options.threshold !== null) {
				valid = distance >= options.threshold;
			}
			
            return valid;
		}

		function validateFingers() {
           
    		return ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH);
    	}

	   function validateEndPoint() {
             	
		    return fingerData[0].end.x !== 0;
        }


        function hasTap() {
         
        	return !!(options.tap) ;
        }

        function triggerHandlerForGesture(event, phase, gesture) {	
        	
        	var ret=undefined;
        	
        	//console.log(phase,PHASE_END)
        	if(gesture==SWIPE) {
        	 
        		 $element.trigger('swipeStatus', [phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData]);
        		
        	 
        		if (options.swipeStatus) {
        			　
        			ret = options.swipeStatus.call($element, event, phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData,$element);
         
        			if(ret===false) return false;
        		}
        		
        		if(phase == PHASE_CANCEL)
        		{

        			$element.trigger('swipe', [direction, distance, duration, fingerCount, fingerData]);
        			
        			if (options.swipe) {
        			  
        				ret = options.swipe.call($element, event, direction, distance, duration, fingerCount, fingerData);
        			
        				if(ret===false) return false;
        			}

        		}
        	
        	 
        		if (phase == PHASE_END && validateSwipe()) {
        			 
        			$element.trigger('swipe', [direction, distance, duration, fingerCount, fingerData]);
        			
        		 
        			if (options.swipe) {
        			  
        				ret = options.swipe.call($element, event, direction, distance, duration, fingerCount, fingerData);
        			
        				if(ret===false) return false;
        			}
        			
        		 
        			switch (direction) {
        				case LEFT:
        				 	$element.trigger('swipeLeft', [direction, distance, duration, fingerCount, fingerData]);

        					if (options.swipeLeft) {
        						ret = options.swipeLeft.call($element, event, direction, distance, duration, fingerCount, fingerData);
        					}
        					break;
        
        				case RIGHT:

        					 $element.trigger('swipeRight', [direction, distance, duration, fingerCount, fingerData]);
        			 
        					if (options.swipeRight) {
        							 
        						ret = options.swipeRight.call($element, event, direction, distance, duration, fingerCount, fingerData);
        					}
        					break;
        
        				case UP:  
        			        $element.trigger('swipeUp', [direction, distance, duration, fingerCount, fingerData]);
        			
        			   		if (options.swipeUp) {
        						ret = options.swipeUp.call($element, event, direction, distance, duration, fingerCount, fingerData);
        					}
        					break;
        
        				case DOWN:
        					$element.trigger('swipeDown', [direction, distance, duration, fingerCount, fingerData]);
        					if (options.swipeDown) {
        						ret = options.swipeDown.call($element, event, direction, distance, duration, fingerCount, fingerData);
        					}
        					break;
        			}
        		}
        	}
        }


        function createFingerData( index, evt ) {
        	var id = evt.identifier!==undefined ? evt.identifier : 0; 

        	fingerData[index].identifier = id;
        	fingerData[index].start.x = fingerData[index].end.x = evt.pageX||evt.clientX;
        	fingerData[index].start.y = fingerData[index].end.y = evt.pageY||evt.clientY;
    
        	return fingerData[index];
        }

        function setTouchInProgress(val) {
        	
        	 
        	if(val===true) {
        		$element.bind(MOVE_EV, touchMove);
        		$element.bind(END_EV, touchEnd);
        		
        	 
        		if(LEAVE_EV) { 
        			$element.bind(LEAVE_EV, touchLeave);
        		}
        	} else {
        		$element.unbind(MOVE_EV, touchMove, false);
        		$element.unbind(END_EV, touchEnd, false);
        	
        	 
        		if(LEAVE_EV) { 
        			$element.unbind(LEAVE_EV, touchLeave, false);
        		}
        	}
        	
      
        	$element.data(PLUGIN_NS+'_intouch', val === true);
        }
        

        function getTimeStamp() {
        	var now = new Date();
        	return now.getTime();
        }

        function touchCancel() {
        	 
        	fingerCount = 0;
        	endTime = 0;
        	startTime = 0;
        	startTouchesDistance=0;
        	endTouchesDistance=0;
        	pinchZoom=1;
        	
         
        	cancelMultiFingerRelease();
        	
        	setTouchInProgress(false);
        }
        
        function inMultiFingerRelease() {
        	
        	var withinThreshold = false;
        	
        	if(previousTouchEndTime) {	
        		var diff = getTimeStamp() - previousTouchEndTime	
        		if( diff<=options.fingerReleaseThreshold ) {
        			withinThreshold = true;
        		}
        	}
        	
        	return withinThreshold;	
        }
        
        function updateFingerData(evt) {
        	
        	var id = evt.identifier!==undefined ? evt.identifier : 0; 
        	var f = getFingerData( id );
        	
        	f.end.x = evt.pageX||evt.clientX;
        	f.end.y = evt.pageY||evt.clientY;
      
        	return f;
        }

        function getFingerData( id ) {
        	for(var i=0; i<fingerData.length; i++) {
        		if(fingerData[i].identifier == id) {
        			return fingerData[i];	
        		}
        	}
        }

        function calculateDirection(startPoint, endPoint ) {
        	var angle = calculateAngle(startPoint, endPoint);

        	if ((angle <= 45) && (angle >= 0)) {
        		return LEFT;
        	} else if ((angle <= 360) && (angle >= 315)) {
        		return LEFT;
        	} else if ((angle >= 135) && (angle <= 225)) {
        		return RIGHT;
        	} else if ((angle > 45) && (angle < 135)) {
        		return DOWN;
        	} else {
        		return UP;
        	}
        }

        function calculateAngle(startPoint, endPoint) {
        	var x = startPoint.x - endPoint.x;
        	var y = endPoint.y - startPoint.y;
        	var r = Math.atan2(y, x);  
        	var angle = Math.round(r * 180 / Math.PI);  

         
        	if (angle < 0) {
        		angle = 360 - Math.abs(angle);
        	}

        	return angle;
        }

        function validateDefaultEvent(jqEvent, direction) {
        	if (options.allowPageScroll === NONE || hasPinches()) {
        		jqEvent.preventDefault();
        	} else {
        		var auto = options.allowPageScroll === AUTO;

        		switch (direction) {
        			case LEFT:
        				if ((options.swipeLeft && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
        					jqEvent.preventDefault();
        				}
        				break;

        			case RIGHT:
        				if ((options.swipeRight && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
        					jqEvent.preventDefault();
        				}
        				break;

        			case UP:
        				if ((options.swipeUp && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
        					jqEvent.preventDefault();
        				}
        				break;

        			case DOWN:
        				if ((options.swipeDown && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
        					jqEvent.preventDefault();
        				}
        				break;
        		}
        	}

        }

        function calculateDistance(startPoint, endPoint) {
			return Math.round(Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2)));
		}

		function calculateDuration() {
			return endTime - startTime;
		}

		function setMaxDistance(direction, distance) {
    		distance = Math.max(distance, getMaxDistance(direction) );
    		maximumsMap[direction].distance = distance;
		}


		function getMaxDistance(direction) {
			if (maximumsMap[direction]) return maximumsMap[direction].distance;
			return undefined;
		}
        
		function touchMove(jqEvent) {
			

			var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent;
			
			//console.log(phase)
			if (phase === PHASE_END || phase === PHASE_CANCEL || inMultiFingerRelease())
				return;

			var ret,
				evt = SUPPORTS_TOUCH ? event.touches[0] : event;
			
 
			var currentFinger = updateFingerData(evt);
			endTime = getTimeStamp();
			
			if (SUPPORTS_TOUCH) {
				fingerCount = event.touches.length;
			}

			if (options.hold)
				clearTimeout(holdTimeout);

			phase = PHASE_MOVE;

		 
			if(fingerCount==2) {
				
				 
				if(startTouchesDistance==0) {
	 
					createFingerData( 1, event.touches[1] );
					
					startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
				} else {
				 
					updateFingerData(event.touches[1]);
				
					endTouchesDistance = calculateTouchesDistance(fingerData[0].end, fingerData[1].end);
					pinchDirection = calculatePinchDirection(fingerData[0].end, fingerData[1].end);
				}
				
				
				pinchZoom = calculatePinchZoom(startTouchesDistance, endTouchesDistance);
				pinchDistance = Math.abs(startTouchesDistance - endTouchesDistance);
			}
			
			
			if ( (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH || hasPinches() ) {
				
				direction = calculateDirection(currentFinger.start, currentFinger.end);
			 
				validateDefaultEvent(jqEvent, direction);

				 
				distance = calculateDistance(currentFinger.start, currentFinger.end);
				duration = calculateDuration();

              
                setMaxDistance(direction, distance);


				if (options.swipeStatus || options.pinchStatus) {
					ret = triggerHandler(event, phase);
				}
				
				
			 
				if(!options.triggerOnTouchEnd || options.triggerOnTouchLeave) {
					
					var inBounds = true;
					
				 
					if(options.triggerOnTouchLeave) {
						var bounds = getbounds( this );
						inBounds = isInBounds( currentFinger.end, bounds );
					}
					
					 
					if(!options.triggerOnTouchEnd && inBounds) {
						phase = getNextPhase( PHASE_MOVE );
					} 
				 
					else if(options.triggerOnTouchLeave && !inBounds ) {
						phase = getNextPhase( PHASE_END );
					}
						
					if(phase==PHASE_CANCEL || phase==PHASE_END)	{
						triggerHandler(event, phase);
					}				
				}
			}
			else {
				phase = PHASE_CANCEL;
				triggerHandler(event, phase);
			}

			if (ret === false) {
				phase = PHASE_CANCEL;
				triggerHandler(event, phase);
			}
		}


		function touchEnd(jqEvent) {
			 
			var event = jqEvent.originalEvent;
				

			if (SUPPORTS_TOUCH) {
				if(event.touches.length>0) {
					startMultiFingerRelease();
					return true;
				}
			}
			
		 
			if(inMultiFingerRelease()) {	
				fingerCount=previousTouchFingerCount;
			}	
		
		 
			endTime = getTimeStamp();
			
		 
			duration = calculateDuration();
				
		 
			if(didSwipeBackToCancel() || !validateSwipeDistance()) {

			    phase = PHASE_CANCEL;
                triggerHandler(event, phase);
			} else if (options.triggerOnTouchEnd || (options.triggerOnTouchEnd == false && phase === PHASE_MOVE)) {
				 	
				jqEvent.preventDefault(); 
				phase = PHASE_END;

                triggerHandler(event, phase);
			}
		 
			else if (!options.triggerOnTouchEnd && hasTap()) {
                
			    phase = PHASE_END;
			    triggerHandlerForGesture(event, phase, TAP);
			}
			else if (phase === PHASE_MOVE) {
				phase = PHASE_CANCEL;
				triggerHandler(event, phase);
			}

			setTouchInProgress(false);

            return null;
		}

	}
}));
